#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

//1602的地址
unsigned LCDAddr = 0x27;
int BLEN = 1;
unsigned fd;

#include "pigpio.h"

/*
 * 
 * 使用I2C驱动LCD1602液晶显示屏
 * gcc -g -o 1602 1602_pi4j.c -lpigpio -lpthread
 * sudo ./1602
 */
void write_word(int data){
	int temp = data;
	if ( BLEN == 1 )
		temp |= 0x08;
	else{
		temp &= 0xF7;
		printf("BLEN is not 1\n");
	}
	i2cWriteByte(fd, temp);
}

void send_command(int comm){
	int buf;
	// Send bit7-4 firstly
	
	buf = comm & 0xF0;
	buf |= 0x04;			// RS = 0, RW = 0, EN = 1
	write_word(buf);
	gpioSleep(PI_TIME_RELATIVE, 0, 2000);
	buf &= 0xFB;			// Make EN = 0
	write_word(buf);
	printf("send_command buf bit7-4 is %d\n", buf);
	gpioSleep(PI_TIME_RELATIVE, 2, 0);

	// Send bit3-0 secondly
	buf = (comm & 0x0F) << 4;
	buf |= 0x04;			// RS = 0, RW = 0, EN = 1
	write_word(buf);
	gpioSleep(PI_TIME_RELATIVE, 0, 2000);
	buf &= 0xFB;			// Make EN = 0
	write_word(buf);
	printf("send_command buf bit3-0 is %d\n", buf);
}

void send_data(int data){
	
	int buf;

	// Send bit7-4 firstly
	buf = data & 0xF0;
	buf |= 0x05;			// RS = 1, RW = 0, EN = 1
	write_word(buf);
	gpioSleep(PI_TIME_RELATIVE, 0, 2000);
	buf &= 0xFB;			// Make EN = 0
	write_word(buf);
	printf("send_data buf bit7-4 is   %d\n", buf);
	gpioSleep(PI_TIME_RELATIVE, 2, 0);

    // Send bit3-0 secondly
	buf = (data & 0x0F) << 4;
	buf |= 0x05;			// RS = 1, RW = 0, EN = 1
	write_word(buf);
	gpioSleep(PI_TIME_RELATIVE, 0, 2000);
	buf &= 0xFB;			// Make EN = 0
	write_word(buf);
	printf("send_data buf bit3-0 is %d\n",buf);

	
}

void init(){
	send_command(0x33);	// Must initialize to 8-line mode at first
	gpioSleep(PI_TIME_RELATIVE, 0, 5000);
	send_command(0x32);	// Then initialize to 4-line mode
	gpioSleep(PI_TIME_RELATIVE, 0, 5000);
	send_command(0x28);	// 2 Lines & 5*7 dots
	gpioSleep(PI_TIME_RELATIVE, 0, 5000);
	send_command(0x0C);	// Enable display without cursor
	gpioSleep(PI_TIME_RELATIVE, 0, 5000);
	send_command(0x01);	// Clear Screen
	i2cWriteByte(fd, 0x08);
}

void clear(){
	send_command(0x01);	//clear Screen
}

void mywrite(int x, int y, char data[]){
	int addr, i;
	int tmp;
	if (x < 0)  x = 0;
	if (x > 15) x = 15;
	if (y < 0)  y = 0;
	if (y > 1)  y = 1;

	// Move cursor
	addr = 0x80 + 0x40 * y + x;
	send_command(addr);
	
	tmp = strlen(data);
	for (i = 0; i < tmp; i++){
		send_data(data[i]);
		printf("Now   %c   is printed\n", data[i]);
	}
}


int main(int argc, char *argv[]){

	if(gpioInitialise() < 0) return -1;
	fd = i2cOpen(1,LCDAddr,0);
	init();
	char time_str[16];
	time_t now = time(NULL);
    strftime(time_str, sizeof(time_str), "%y-%m-%d %H:%M", localtime(&now));
	mywrite(1, 0, time_str);
	mywrite(1, 1, time_str);
	gpioDelay(2000);
	i2cClose(fd);
	gpioTerminate();
	return 0;
}
